/**
 *  *2010-3-24 下午03:17:36  add 
 */
package com.base.myproject.client.busi;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.base.myproject.client.busi.BO.ModelDataList;
import com.base.myproject.client.busi.BO.SetGetValue;
import com.base.myproject.client.busi.BO.TreeNodeModelData;
import com.base.myproject.client.jdbc.DataSet;
import com.base.myproject.client.jdbc.StoreInfo;
import com.base.myproject.client.system.SystemMessage;
import com.base.myproject.client.tools.CommandFactory;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.StoreListener;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * 树形的store，参照BaseStore
 * 
 * @author Administrator 2010-3-24 javazgw@gmail.com
 */
public class BaseTreeStore<M extends ModelData> extends TreeStore<M> implements
		AsyncCallback<ModelDataList> {
	private BaseTreeStore<ModelData> parent = null; // 主表
	private ArrayList<BaseTreeStore<M>> chilestore = new ArrayList<BaseTreeStore<M>>(); // 子表
	private String name = null;
	private int curcowindex = -1; // 当前所在行
	private String tablename = null;// 表表名
	private String[] keyname = null;// new String[] { "gcode" };// 主键
	String[] linkparentcolumns = null; // 与主表关联的字段 (主表字段)
	String[] linkparent_chile_columns = null;// 与主表关联的字段（子表字段）
												// 子表与主表关联字段，用于子表添加记录的时候保持和主表内容一致
	StoreInfo storeinfo = null;
	// 行增加的默认值
	java.util.HashMap<String, Object> defaultvalue = new java.util.HashMap<String, Object>();
	boolean needsave = true;// 默认需要保存，

	// final BaseTreeStore _this;
	// sotre的所有元素
	ModelDataList list = new ModelDataList();

	private Map<BaseStoreEvent.EventType, List> listeners;

	public BaseTreeStore() {
		// super();
		// _this = this;
		// EditorTreeGrid<ModelData> tree = new EditorTreeGrid<ModelData>(store,
		// cm);
	}

	public BaseTreeStore(/* ModelType type, */StoreInfo storeinfo,
			boolean autoload) {
		this(/* type, */storeinfo, autoload, 1);
	}

	public BaseTreeStore(/* ModelType type, */StoreInfo storeinfo,
			boolean autoload, int mode) {

		this();
		this.storeinfo = storeinfo;
		// this.mode = mode;
		// this.autoload = autoload;
		// setType(type);
		// setStoreinfo(storeinfo);
		//
		// // 如果是直接设置的方式自动读取记录
		// initcompleted();
		// // loader.load();
		this.addStoreListener(new StoreListener<M>() {

		});
		if(autoload)
		load();
	}

	/**
	 * 跳转到某一行，通常情况下有grid触发，然后触发行改变的事件
	 * 
	 * @param index
	 * @return
	 */
	public ModelData gotorow(int index) {
		// 如果行没有发生改变不触发事件
		// if (curcowindex != index) 这句话被屏蔽是因为在做过滤的时候，光标如果都在第一行 就不会触发行改变，导致数据
		// （在form中）未能正常显示
		// if (curcowindex != index)
		{
			BaseStoreEvent be = new BaseStoreEvent(this);
			curcowindex = index;
			be.setBasetreestore(this);
			be.setCurrowindex(curcowindex);
			this.fireEvent(BaseStoreEvent.EventType.ROW_CHANGED, be);
		}
		return getAllItems().get(index);
		// return getAt(index);
	}

	public M getAt(int index) {
		return getAllItems().get(index);
	}

	public Object getValue(int row, String name) {
		return getAt(row).get(name);

	}

	public Object getValue(String name) {
		return getValue(curcowindex, name);
	}

	/**
	 * 添加记录
	 */
	public void add(M item, boolean addChildren) {
		if (item instanceof TreeNodeModelData) {
			((TreeNodeModelData) item).setStoreinfo(storeinfo);
			((TreeNodeModelData) item).addnewRecord(storeinfo, "", "");
			// ((TreeNodeModelData)list.getModels().get(0)).addNodeSort((TreeNodeModelData)item);
		}

		super.add(item, addChildren);

	}



	public void add() {
		TreeNodeModelData tnmd = new TreeNodeModelData(storeinfo, true);
		add((M) tnmd, true);
	}
	//删除的功能我改了。——林乐鹏
	public void remove() {
		if (curcowindex > 0)
			remove(getAt(curcowindex));
	}

	public void remove(M item) {

		if (item instanceof TreeNodeModelData) {
			((TreeNodeModelData) item).setBusistatus(SetGetValue.DELETE);
		}
		super.remove(item);

	}

	/**
	 * 读取数据
	 */
	

	public void load() {
		BaseStoreEvent be = new BaseStoreEvent(this);
		be.setBasetreestore(this);
		fireEvent(BaseStoreEvent.EventType.LOAD_STARTED, be);
		final com.base.myproject.client.tools.GreetingServiceAsync greetingService = GWT
		.create(com.base.myproject.client.tools.GreetingService.class);
		
		greetingService.getModelDataList(storeinfo, 1, this);
		

	}

	/**
	 * 读取数据失败
	 */
	// @Override
	public void onFailure(Throwable caught) {
		caught.printStackTrace();
	}

	/**
	 * 读取数据成功返回
	 */
	// @Override
	public void onSuccess(ModelDataList result) {

		this.removeAll();
		
		this.add((List<M>) ((TreeNodeModelData) result.getModels().get(0))
				.getChildren(), true);

		BaseStoreEvent be = new BaseStoreEvent(this);
		be.setBasetreestore(this);
		fireEvent(BaseStoreEvent.EventType.LOAD_COMPLETE, be);
	
	}

	/**
	 * 保存，全部保存
	 */
	public boolean trySave() {
		final java.util.Vector<String> v = new java.util.Vector<String>();
		// this.getChilestore()
		v.addAll(_trySave());
		com.base.myproject.client.tools.Command c1 = new com.base.myproject.client.tools.Command() {
			public void Start() {
				final com.base.myproject.client.tools.GreetingServiceAsync greetingService = GWT
						.create(com.base.myproject.client.tools.GreetingService.class);
				greetingService.saveBaseObject(v, null,
						new AsyncCallback<String>() {
							public void onFailure(Throwable caught) {
								// Show the RPC error message to the user
								Complete();
								MessageBox
										.alert(
												"提示",
												"保存失败。\n网络连接失败!请稍候保存数据！\n根据你使用网络的状况，你可能需要等待几分钟之后再尝试重新链接。\n如果你关闭窗口数据可能丢失。",
												null);

							}

							public void onSuccess(String result) {
								Complete();
								if (result.equals(SystemMessage
										.getMessage(4, 0))) {
									// 成功保存才设置状态，否则不设置，用户可以稍后保存
									_trySaveed();

									Info.display("", "保存成功", "");
								} else {
									MessageBox
											.alert(
													"提示",
													"保存失败。\n网络忙碌，与服务器交互失败!请稍候保存数据！\n根据你使用网络的状况，你可能需要等待几分钟之后再尝试重新链接。\n如果你关闭窗口数据可能丢失。错误还可能是："
															+ result, null);
								}

							}
						});
			}
		};

		CommandFactory.addCommand(c1);
		GWT.log(v.toString(), null);
		return true;
	}

	public java.util.Vector<String> _trySave() {
		java.util.Vector<String> v = new java.util.Vector<String>();
		// 不需要保存，估计外部另外设置了保存的sql，处理特殊事务。默认保存sql取消。
		if (!isNeedsave()) {
			this.commitChanges();
			return v;
		}

		for (M m : this.getModels()) {
			
			if (m instanceof TreeNodeModelData) {

				int status = ((TreeNodeModelData) m).getBusistatus();
				if (status == SetGetValue.NOTHING) {
					continue;
				}
				System.out.println(m.get("icode"));
				if ((status & SetGetValue.DELETE) == SetGetValue.DELETE) {
					String delete = ((TreeNodeModelData) m).delete();
					if (delete != null)
						v.add(delete);
				} else if ((status & SetGetValue.INSERT) == SetGetValue.INSERT) {
					// System.out.println(((BaseObject)this.getModels().get(i)).insert());
					String insert = ((TreeNodeModelData) m).insert();
					if (insert != null)
						v.add(insert);
				} else if ((status & SetGetValue.UPDATE) == SetGetValue.UPDATE) {
					// System.out.println(((BaseObject)this.getModels().get(i)).update());
					String update = ((TreeNodeModelData) m).update();
					// GWT.log("update in trysave="+update, null);
					if (update != null)
						v.add(update);
				}
				// System.out.println("delete = "+((TreeNodeModelData)
				// m).delete());
				// System.out.println("update="+((TreeNodeModelData)
				// m).update());
				// System.out.println("insert="+((TreeNodeModelData)
				// m).insert());
			}
		}
		/**
		 * 暂时不支持 子表
		 */
		// if (this.getChilestore().size() > 0) {
		// for (int i = 0; i < this.getChilestore().size(); i++) {
		// v.addAll(this.getChilestore().get(i)._trySave());
		// }
		// }
		return v;

	}

	public java.util.Vector<String> _trySave(int rownum) {
		return null;
	}

	public void _trySaveed() {

	}

	public void _trySaveed(int rownum) {

	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getCurcowindex() {
		return curcowindex;
	}

	public void setCurcowindex(int curcowindex) {
		this.curcowindex = curcowindex;
	}

	public String getTablename() {
		return tablename;
	}

	public void setTablename(String tablename) {
		this.tablename = tablename;
	}

	public String[] getLinkparentcolumns() {
		return linkparentcolumns;
	}

	public void setLinkparentcolumns(String[] linkparentcolumns) {
		this.linkparentcolumns = linkparentcolumns;
	}

	public String[] getLinkparent_chile_columns() {
		return linkparent_chile_columns;
	}

	public void setLinkparent_chile_columns(String[] linkparentChileColumns) {
		linkparent_chile_columns = linkparentChileColumns;
	}

	public StoreInfo getStoreinfo() {
		return storeinfo;
	}

	public void setStoreinfo(StoreInfo storeinfo) {
		this.storeinfo = storeinfo;
	}

	public java.util.HashMap<String, Object> getDefaultvalue() {
		return defaultvalue;
	}

	public void setDefaultvalue(java.util.HashMap<String, Object> defaultvalue) {
		this.defaultvalue = defaultvalue;
	}

	public boolean isNeedsave() {
		return needsave;
	}

	public void setNeedsave(boolean needsave) {
		this.needsave = needsave;
	}

	public int getCount() {

		return this.getModels().size();
	}

	public ModelDataList getList() {
		return list;
	}

	/*
	 * 设置model的所有元素
	 */
	public void setList(ModelDataList list) {
		this.list = list;
		this.add(list.getModels(), true);
	}

	public boolean fireEvent(BaseStoreEvent.EventType eventType,
			BaseStoreEvent be) {
		if (listeners != null) {

			List<BaseStoreListener> list = listeners.get(eventType);
			if (list != null) {
				for (BaseStoreListener l : list) {

					l.BaseStoreEventHandle(be);
				}
			}

		}
		return true;
	}

	public void addBaseStoreListener(BaseStoreEvent.EventType eventType,
			BaseStoreListener listener) {
		if (listener == null)
			return;
		if (listeners == null) {
			listeners = new HashMap<BaseStoreEvent.EventType, List>();
		}
		List<BaseStoreListener> list = listeners.get(eventType);
		if (list == null) {
			list = new ArrayList<BaseStoreListener>();
			listeners.put(eventType, list);
		}

		if (!list.contains(listener)) {
			list.add(listener);
		}

	}

	public void removeBaseStoreListener(BaseStoreEvent.EventType eventType) {
		if (listeners == null)
			return;
		listeners.remove(eventType);
	}

	public void removeBaseStoreListener(BaseStoreEvent.EventType eventType,
			final BaseStoreListener listener) {
		if (listeners == null) {
			return;
		}

		List<Listener> list = listeners.get(eventType);
		if (list != null) {
			list.remove(listener);
			if (list.isEmpty()) {
				listeners.remove(eventType);
			}
		}

	}

}
